﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Mvc.XForms.Controls.Settings;
using Mvc.XForms.Utilities;

namespace Mvc.XForms.Controls {
	public abstract class XFormContextBase<TParentContext, TContext> : ContainerControlBase<TContext>, IContext<TContext> {
		protected XFormContextBase(IContainerControl parent, Expression bindBody)
			: base(parent, bindBody) { }

		#region Generic controls

		public GroupSettings<T> Group<T>(Expression<Func<TContext, T>> bind) {
			var group = new XFormGroup<TContext, T>(this, bind);
			return group.Settings;
		}

		public RepeatSettings<T> Repeat<T>(Expression<Func<TContext, IEnumerable<T>>> bind) {
			var repeat = new XFormRepeat<TContext, T>(this, bind);
			return repeat.Settings;
		}

		public SelectSettings Select<TEnum>(Expression<Func<TContext, IEnumerable<TEnum>>> enumBind) {
			var enums = Select<TContext, TEnum>.GetEnumList(enumBind);
			return Select(enumBind, enums, t => t, t => t.ToString().CapitalizeSpace());
		}

		public SelectSettings Select<T>(Expression<Func<TContext, IEnumerable<T>>> bind, IEnumerable<T> items) {
			return Select(bind, items, t => t, t => t);
		}

		public SelectSettings Select<T>(Expression<Func<TContext, IEnumerable<T>>> bind, IEnumerable<T> items, Expression<Func<T, object>> valueSelector, Func<T, object> labelSelector) {
			var select = new Select<TContext, T>(this, bind, items, valueSelector, labelSelector);
			return select.Settings;
		}

		public Select1Settings Select1<TEnum>(Expression<Func<TContext, TEnum>> enumBind) {
			var enums = Select1<TContext, TEnum>.GetEnumList(enumBind);
			return Select1(enumBind, enums, t => t, t => t.ToString().CapitalizeSpace());
		}

		public Select1Settings Select1<T>(Expression<Func<TContext, T>> bind, IEnumerable<T> items) {
			return Select1(bind, items, t => t, t => t);
		}

		public Select1Settings Select1<T>(Expression<Func<TContext, T>> bind, IEnumerable<T> items, Expression<Func<T, object>> valueSelector, Func<T, object> labelSelector) {
			var select1 = new Select1<TContext, T>(this, bind, items, valueSelector, labelSelector);
			return select1.Settings;
		}

		#endregion
	}
}